package com.ruoyi.common.config;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: zk
 * @Date: 2022/11/01/14:40
 * @Description: 记录用户请求接口消息与消耗时间
 */
@Aspect
@Component
@Slf4j
@Profile({"dev"})
public class ControllerLog {
    /**
     * 以 controller 包下定义的所有请求为切入点
     */
    @Pointcut("execution( * com.ruoyi.*.controller..*.*(..))")
    public void webLog() {
    }

    /**
     * 在切点之前织入
     *
     * @param joinPoint 连接点
     */
    @Before("webLog()")
    public void doBefore(final JoinPoint joinPoint) {
        // 开始打印请求日志
        final ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        final HttpServletRequest request = attributes.getRequest();
        // 打印请求相关参数
        log.info("========================================== 请求开始 ==========================================");
        // 打印请求 url
        log.info("URL                  : {}", request.getRequestURL().toString());
        // 打印 Http method
        log.info("HTTP Method      : {}", request.getMethod());
        // 打印调用 controller 的全路径以及执行方法
        log.info("Class Method    : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
        final Enumeration params = request.getParameterNames();
        while (params.hasMoreElements()) {
            final String paramName = (String) params.nextElement();
            log.info(paramName + ":{}", request.getParameter(paramName));
        }
    }

    /**
     * 环绕
     *
     * @param proceedingJoinPoint 连接点
     * @return 内容
     * @throws Throwable 环绕异常
     */
    @Around("webLog()")
    public Object doAround(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        final long startTime = System.currentTimeMillis();
        final Object result = proceedingJoinPoint.proceed();
        // 打印出参
        log.info("Response Args   : {}", JSON.toJSON(result));
        // 执行耗时
        log.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
        log.info("=========================================== 请求结束 ===========================================");
        return result;
    }
}
